package com.cinema.util;

import com.cinema.entity.hall.Hall;
import com.cinema.entity.movie.Movie;
import com.cinema.entity.movie.Schedule;
import com.cinema.entity.ticket.Ticket;
import com.cinema.entity.user.AbstractUser;
import com.cinema.entity.user.AdminUser;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 数据存储工具类（单例模式）
 */
public class DataStore {
    private static DataStore instance;
    private final String DATA_DIR = "src/main/resources/data/"; // 数据存储目录

    // 数据文件路径
    private final String USER_FILE = DATA_DIR + "users.ser";
    private final String MOVIE_FILE = DATA_DIR + "movies.ser";
    private final String HALL_FILE = DATA_DIR + "halls.ser";
    private final String SCHEDULE_FILE = DATA_DIR + "schedules.ser";
    private final String TICKET_FILE = DATA_DIR + "tickets.ser";

    // 数据集合
    private List<AbstractUser> userList;
    private List<Movie> movieList;
    private List<Hall> hallList;
    private List<Schedule> scheduleList;
    private List<Ticket> ticketList;

    // 单例模式：私有构造
    private DataStore() {
        try {
            // 创建数据目录（如果不存在）
            Files.createDirectories(Paths.get(DATA_DIR));
        } catch (IOException e) {
            System.err.println("⚠️ 数据目录创建失败：" + e.getMessage());
        }

        // 加载数据（如果文件不存在则初始化空列表）
        userList = loadData(USER_FILE);
        movieList = loadData(MOVIE_FILE);
        hallList = loadData(HALL_FILE);
        scheduleList = loadData(SCHEDULE_FILE);
        ticketList = loadData(TICKET_FILE);

        // 初始化默认数据（首次运行时）
        initDefaultData();
    }

    // 获取单例实例
    public static DataStore getInstance() {
        if (instance == null) {
            synchronized (DataStore.class) {
                if (instance == null) {
                    instance = new DataStore();
                }
            }
        }
        return instance;
    }

    // 初始化默认数据
    private void initDefaultData() {
        // 1. 默认管理员（admin/123456）
        if (userList.isEmpty()) {
            userList.add(new AdminUser(
                    "AD001",
                    "admin",
                    "123456",
                    LocalDateTime.now(),
                    "管理员",
                    "13800138000"
            ));
            saveData(USER_FILE, userList);
        }

        // 2. 默认放映厅（2个）
        if (hallList.isEmpty()) {
            hallList.add(new Hall("H001", "1号厅", 5, 10));
            hallList.add(new Hall("H002", "2号厅", 8, 12));
            saveData(HALL_FILE, hallList);
        }
    }

    // 加载序列化数据
    @SuppressWarnings("unchecked")
    private <T> List<T> loadData(String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            return new ArrayList<>();
        }

        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
            return (List<T>) ois.readObject();
        } catch (Exception e) {
            System.err.println("⚠️ 加载数据失败（" + filePath + "）：" + e.getMessage());
            return new ArrayList<>();
        }
    }

    // 保存序列化数据
    private <T> void saveData(String filePath, List<T> data) {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath))) {
            oos.writeObject(data);
        } catch (IOException e) {
            System.err.println("❌ 保存数据失败（" + filePath + "）：" + e.getMessage());
        }
    }

    // Getter和数据更新方法
    public List<AbstractUser> getUserList() { return userList; }
    public void updateUserList() { saveData(USER_FILE, userList); }

    public List<Movie> getMovieList() { return movieList; }
    public void updateMovieList() { saveData(MOVIE_FILE, movieList); }

    public List<Hall> getHallList() { return hallList; }
    public void updateHallList() { saveData(HALL_FILE, hallList); }

    public List<Schedule> getScheduleList() { return scheduleList; }
    public void updateScheduleList() { saveData(SCHEDULE_FILE, scheduleList); }

    public List<Ticket> getTicketList() { return ticketList; }
    public void updateTicketList() { saveData(TICKET_FILE, ticketList); }
}
